#include "channel_output.h"

/* 内部参数管理函数 - 直接操作参数结构体 */
static uint16_t GetVoltageParam(uint8_t channel)
{
    switch(channel)
    {
        case 1: return g_tChannelOutputParam.channel1_voltage;
        case 2: return g_tChannelOutputParam.channel2_voltage;
        case 3: return g_tChannelOutputParam.channel3_voltage;
        case 4: return g_tChannelOutputParam.channel4_voltage;
        default: return 0;
    }
}

static uint16_t GetCurrentParam(uint8_t channel)
{
    switch(channel)
    {
        case 1: return g_tChannelOutputParam.channel5_current;
        case 2: return g_tChannelOutputParam.channel6_current;
        default: return 0;
    }
}

static void SetVoltageParam(uint8_t channel, uint16_t value)
{
    switch(channel)
    {
        case 1: 
            g_tChannelOutputParam.channel1_voltage = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel1_voltage);
            break;
        case 2: 
            g_tChannelOutputParam.channel2_voltage = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel2_voltage);
            break;
        case 3: 
            g_tChannelOutputParam.channel3_voltage = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel3_voltage);
            /* 通道3电压与通道7电流联动 - 通道7电流值通过通道3电压值计算得出 */
            break;
        case 4: 
            g_tChannelOutputParam.channel4_voltage = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel4_voltage);
            /* 通道4电压与通道8电流联动 - 通道8电流值通过通道4电压值计算得出 */
            break;
        default: 
            break;
    }
}

static void SetCurrentParam(uint8_t channel, uint16_t value)
{
    switch(channel)
    {
        case 1: 
            g_tChannelOutputParam.channel5_current = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel5_current);
            break;
        case 2: 
            g_tChannelOutputParam.channel6_current = value;
            SaveSingleParamByAddr(&g_tChannelOutputParam.channel6_current);
            break;
        default: 
            break;
    }
}

/* 应用所有通道输出到硬件 */
void ChannelOutput_ApplyAll(void)
{
    /* 电压输出通道（1~4）*/
    pwmdac_set_voltage(1, GetVoltageParam(1));
    pwmdac_set_voltage(2, GetVoltageParam(2));
    pwmdac_set_voltage(3, GetVoltageParam(3));
    pwmdac_set_voltage(4, GetVoltageParam(4));
    
    /* 电流输出通道（5~8）*/
    dac_set_current_4_20ma(1, GetCurrentParam(1)); /* 5 */
    dac_set_current_4_20ma(2, GetCurrentParam(2)); /* 6 */

//    pwmdac_set_current_4_20ma(3, GetVoltageParam(3) * 10); /* 7 (与通道3电压联动) ，不需要另外设置*/
//    pwmdac_set_current_4_20ma(4, GetVoltageParam(4) * 10); /* 8 (与通道4电压联动) ，不需要另外设置*/
}

void ChannelOutput_SetVoltage(uint8_t channel, uint16_t value)
{
    if(channel >= 1 && channel <= 4) 
    {
        SetVoltageParam(channel, value);
        pwmdac_set_voltage(channel, value);
    }
}

void ChannelOutput_SetCurrent(uint8_t channel, uint16_t value)
{
    if(channel == 5) 
    {
        SetCurrentParam(1, value);
        dac_set_current_4_20ma(1, value);
    } 
    else if(channel == 6) 
    {
        SetCurrentParam(2, value);
        dac_set_current_4_20ma(2, value);
    } 
    else if(channel == 7) 
    {
        /* 通道7电流设置：将电流值转换为电压值并存储到通道3电压参数中 */
        uint16_t voltage = value / 10; /* 电流/10 = 电压 */
        g_tChannelOutputParam.channel3_voltage = voltage;
        SaveSingleParamByAddr(&g_tChannelOutputParam.channel3_voltage);
        pwmdac_set_current_4_20ma(3, value);
    }
    else if(channel == 8) 
    {
        /* 通道8电流设置：将电流值转换为电压值并存储到通道4电压参数中 */
        uint16_t voltage = value / 10; /* 电流/10 = 电压 */
        g_tChannelOutputParam.channel4_voltage = voltage;
        SaveSingleParamByAddr(&g_tChannelOutputParam.channel4_voltage);
        pwmdac_set_current_4_20ma(4, value);
    }
}

uint16_t ChannelOutput_GetVoltage(uint8_t channel)
{
    if(channel >= 1 && channel <= 4) 
    {
        return GetVoltageParam(channel);
    }
    return 0;
}

uint32_t ChannelOutput_GetCurrent(uint8_t channel)
{
    if(channel >= 5 && channel <= 8) 
    {
        if(channel == 5) return GetCurrentParam(1);
        if(channel == 6) return GetCurrentParam(2);
        if(channel == 7) return (uint32_t)GetVoltageParam(3) * 10; /* 与通道3电压联动 */
        if(channel == 8) return (uint32_t)GetVoltageParam(4) * 10; /* 与通道4电压联动 */
    }
    return 0;
}

/**
 * @brief 获取通道实际输出值（从硬件读取）
 * @param channel 通道号 (1-8)
 * @return float 实际输出值，电压单位为V，电流单位为mA
 */
float ChannelOutput_GetActualOutput(uint8_t channel)
{
    uint16_t ccr_value = 0;
    float duty, voltage, current;
    
    switch (channel)
    {
    case 1: /* PWMDAC1 电压输出 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC1_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f;
        return voltage; /* V */
        
    case 2: /* PWMDAC2 电压输出 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC2_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f;
        return voltage; /* V */
        
    case 3: /* PWMDAC3 电压输出 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC3_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f;
        return voltage; /* V */
        
    case 4: /* PWMDAC4 电压输出 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC4_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f;
        return voltage; /* V */
        
    case 5: /* DAC1 电流输出 */
    {
        uint16_t dac1_value = HAL_DAC_GetValue(&g_dac_handle, DAC_CHANNEL_1);
        voltage = (float)dac1_value * (g_vdda_voltage / 4096.0f);
        current = 10.0f * voltage; /* mA */
        return current;
    }
    
    case 6: /* DAC2 电流输出 */
    {
        uint16_t dac2_value = HAL_DAC_GetValue(&g_dac_handle, DAC_CHANNEL_2);
        voltage = (float)dac2_value * (g_vdda_voltage / 4096.0f);
        current = 10.0f * voltage; /* mA */
        return current;
    }
    
    case 7: /* PWMDAC3 电流输出 (与通道3电压联动) */
        /* 从硬件获取PWMDAC3的实际占空比，然后计算电流 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC3_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f; /* 10V * duty/100 */
        current = voltage * 10.0f; /* 电流 = 电压 * 10 */
        return current; /* mA */
        
    case 8: /* PWMDAC4 电流输出 (与通道4电压联动) */
        /* 从硬件获取PWMDAC4的实际占空比，然后计算电流 */
        ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC4_TIMX_CHY);
        duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
        voltage = duty * 0.1f; /* 10V * duty/100 */
        current = voltage * 10.0f; /* 电流 = 电压 * 10 */
        return current; /* mA */
        
    default:
        break;
    }
    return 0.0f;
} 
